package com.gwd.task.exception;

import com.gwd.task.model.CallResultMsg;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhiyongming
 * @date 2020/11/9 15:58
 */
@Component
@RestControllerAdvice(annotations = RestController.class)
public class GlobalExceptionHandler {

    /**
     * MethodArgumentNotValidException
     * @return CallResultMsg
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg<?> handle(MethodArgumentNotValidException exception) {
        String message = exception.getMessage();
        return CallResultMsg.Fail(message);
    }
    /**
     * ValidationException
     * @return CallResultMsg
     */
    @ExceptionHandler(ValidationException.class)
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg<?> handle(ValidationException exception) {
        String message = "";
        if(exception instanceof ConstraintViolationException){
            ConstraintViolationException exs = (ConstraintViolationException) exception;
            Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
            message = violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(","));
        }
        return CallResultMsg.Fail(message);
    }

    /**
     * MissingServletRequestParameterException
     * Request 参数请求接口捕获
     * @return CallResultMsg
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg<?> handle(MissingServletRequestParameterException e) {
        String message = e.getMessage();
        return CallResultMsg.Fail(message);
    }

    /**
     * BindException
     * Valid 验证
     * @return CallResultMsg
     */
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg<?> handle(BindException e) {
        List<ObjectError> allErrors = e.getAllErrors();
        String message = allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
        return CallResultMsg.Fail(message);
    }

    /**
     * DataException
     * 数据错误
     * @return CallResultMsg
     */
    @ExceptionHandler(DataException.class)
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg<?> handle(DataException e) {
        String message = e.getMessage();
        return CallResultMsg.Fail(message);
    }

    /**
     * UnAuthorizationException
     * 认证过期
     * @return CallResultMsg
     */
    @ExceptionHandler(UnAuthorizationException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CallResultMsg<?> handle(UnAuthorizationException e) {
        if (e.getType()==1) {
            return CallResultMsg.LoginFail();
        }
        if (e.getType()==2) {
            return CallResultMsg.UserDisabled();
        }
        return CallResultMsg.Unauthorized();
    }

    /**
     * 文件大小超过限制
     * @param ex 1
     * @return 2
     */
    @ExceptionHandler(value = SizeLimitExceededException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CallResultMsg<?> handle(SizeLimitExceededException ex) {
        return CallResultMsg.LoginFail();
    }

    /**
     * 文件大小超过限制
     * @param ex 1
     * @return 3
     */
    @ExceptionHandler(value = FileSizeLimitExceededException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CallResultMsg<?> handle(FileSizeLimitExceededException ex) {
        return CallResultMsg.LoginFail();
    }
    /*
     * RuntimeException
     * @return CallResultMsg
     */
//    @ExceptionHandler(RuntimeException.class)
//    @ResponseStatus(HttpStatus.BAD_REQUEST)
//    public CallResultMsg<?> handle() {
//        return CallResultMsg.Fail();
//    }

    /*
     *
     */
//    @ExceptionHandler(IllegalArgumentException.class)
//    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
//    public CallResultMsg<?> handle(IllegalArgumentException exception) {
//        String message = exception.getMessage();
//        return CallResultMsg.Error(message);
//    }
}
